/*
 * iShopPlace Project.
 */
package ishopplace.view.bean;

import ishopplace.model.businessobject.Account;
import ishopplace.model.exception.iShopPlaceException;
import ishopplace.view.util.FacesUtils;

import java.util.List;
import java.util.Map;


/**
 * Account backing bean.
 * 
 * @author <a href="mailto:derek@derekshen.com">Derek Y. Shen</a>
 */
public class AccountBean extends BaseBean {
    private Account account;
    private String repeatPassword;
	private String expiryMonth;
	private String expiryYear;
    private boolean loggedin;
	private Map adviceBannerMap;
    
    public AccountBean() {
    	super();
        this.account = new Account();
        this.loggedin = false;
    }
    
    /**
     * Backing bean action to signon a user.
     * 
     * @return the navigation result
     */
	public String signonAction() {
	    this.logger.debug("signonAction is invoked");
	    this.logger.debug("username = " + this.account.getUsername());
	    this.logger.debug("password = " + this.account.getPassword());
	    
		try {
			this.account = this.getServiceLocator().getCustomerService().signon(this.account.getUsername(), this.account.getPassword());
			if (this.account == null) {
			    this.loggedin = false;
			    this.account = new Account();
			    String msg = "Signon failed, please try again.";
			    FacesUtils.addInfoMessage(msg);		    
			    return null;
			}
			this.parseExpiryDate();
			this.prepareMyList();
			this.loggedin = true;
			this.logger.debug("User signed on successfully");
			
			String url = (String)FacesUtils.getSessionAttribute("origRequestUri");
			this.logger.debug("origRequestUri = " + url);
			
			if (url != null) {
			    FacesUtils.removeSessionAttribute("origRequestUri");
			    //in struts u can redirect to another page inside an action,
			    //however, u can not do it in JSF, e.g. 
			    //FacesUtils.getServletResponse().sendRedirect(url);
			    FacesUtils.setRequestAttribute("origRequestUri", url);
			    return NavigationResults.SIGNON_REDIRECT;
			} else {
			    return NavigationResults.SUCCESS;
			}
		} catch (Exception e) {
		    this.loggedin = false;
		    String msg = "Unable to signon: Internal Error";
		    this.logger.error(msg, e);
		    return NavigationResults.FAILURE;
		}
	}
	
	/**
	 * Backing bean action to signoff a user.
	 * 
	 * @return the navigation result
	 */
	public String signoffAction() {
	    this.logger.debug("signoffAction is invoked");
	    this.clear();
	    return NavigationResults.SIGNOFF;
	}
	
	/**
	 * Backing bean action to update an account.
	 * 
	 * @return the navigation result
	 */
	public String updateAction() {
	    this.logger.debug("updateAction is invoked");
	    try {
	    	this.setExpiryDate();
	        this.getServiceLocator().getCustomerService().updateAccount(this.account);
	        String msg = "Account is updated successfully";
	        FacesUtils.addInfoMessage(msg);
	        this.prepareMyList();
	        return NavigationResults.SUCCESS;
	    } catch (iShopPlaceException me) {
	        String msg = "Unable to update account: Internal Error";
	        this.logger.error(msg, me);
	        return NavigationResults.FAILURE;
	    }
	}
	
	/**
	 * Backing bean action to create a new signon.
	 * 
	 * @return the navigation result
	 */
	public String createSignonAction() {
	    this.logger.debug("createSignonAction is invoked");
	    String username = this.account.getUsername();
	    String password = this.account.getPassword();
	    String repeatPassword = this.repeatPassword;
	    
	    //clear the account in session
	    this.clear();
	    this.account.setUsername(username);
	    this.account.setPassword(password);
	    this.repeatPassword = repeatPassword;
	    
	    if (!this.repeatPassword.equals(this.account.getPassword())) {
	        this.logger.debug("Passwords do not match");
	        FacesUtils.addErrorMessage("repeatPassword", "Passwords do not match.");
	        return null;
	    } else {
	        return NavigationResults.SUCCESS;
	    }
	}
	
	/**
	 * Backing bean action to create a new account.
	 * 
	 * @return the navigation result
	 */
	public String createAction() {
	    this.logger.debug("createAction is invoked");
	    try {
	    	this.setExpiryDate();
	        this.getServiceLocator().getCustomerService().saveAccount(this.account);
	        this.prepareMyList();
	        this.loggedin = true;
	        this.logger.debug("Account is created successfully");
	        
			String url = (String)FacesUtils.getSessionAttribute("origRequestUri");
			this.logger.debug("origRequestUri = " + url);
			if (url != null) {
			    FacesUtils.removeSessionAttribute("origRequestUri");
			    FacesUtils.setRequestAttribute("origRequestUri", url);
			    return NavigationResults.SIGNON_REDIRECT;
			} else {
			    return NavigationResults.SUCCESS;
			}
	    } catch (iShopPlaceException me) {
	        String msg = "Unable to create a new account: Internal Error";
	        this.logger.error(msg, me);
	        return NavigationResults.FAILURE;
	    }
	}
	
	public Account getAccount() {
	    return this.account;
	}
	
	public void setAccount(Account newAccount) {
	    this.account = newAccount;
	}
	
	public String getRepeatPassword() {
	    return  this.repeatPassword;
	}
	
	public void setRepeatPassword(String newRepeatPassword) {
	    this.repeatPassword = newRepeatPassword;
	}
	
	public String getExpiryMonth() {
		return this.expiryMonth;
	}
	
	public void setExpiryMonth(String newExpiryMonth) {
		this.expiryMonth = newExpiryMonth;
	}
	
	public String getExpiryYear() {
		return this.expiryYear;
	}
	
	public void setExpiryYear(String newExpiryYear) {
		this.expiryYear = newExpiryYear;
	}
	
	public boolean isLoggedin() {
	    return this.loggedin;
	}
	
	public Map getAdviceBannerMap() {
		return this.adviceBannerMap;
	}
	
	public void setAdviceBannerMap(Map newMap) {
		this.adviceBannerMap = newMap;
	}
	
	//clear the current account.
	private void clear() {
		this.loggedin = false;
		this.expiryMonth = null;
		this.expiryYear = null;
		this.repeatPassword = null;
		this.account = new Account();
	}
	
	private void parseExpiryDate() {
		String expiryDate = this.account.getExpiryDate();
		this.expiryMonth = expiryDate.substring(0, expiryDate.indexOf("/"));
		this.expiryYear = expiryDate.substring(expiryDate.indexOf("/") + 1);
	}
	
	private void setExpiryDate() {
		this.account.setExpiryDate(this.expiryMonth + "/" + this.expiryYear);
	}
	
	/**
	 * Prepare the data needed for the my listing panel.
	 */
	private void prepareMyList() {
		if (this.account.isListOption()) {
			//myList is enabled
			String favoriteCategory = FacesUtils.getSessionBean().getCurrentFavoriteCategory();
			List myList = FacesUtils.getSessionBean().getMyList();
				
			if (!this.account.getFavoriteCategoryId().equals(favoriteCategory) ||
					myList == null) {
				try {
					myList = this.getServiceLocator().getCatalogService().getProductListByCategory(this.account.getFavoriteCategoryId());
					FacesUtils.getSessionBean().setCurrentFavoriteCategory(this.account.getFavoriteCategoryId());
					FacesUtils.getSessionBean().setMyList(myList);
				} catch (iShopPlaceException me) {
					this.logger.error("Could not populate myList ", me);
				}
			}
		}
	}
}
